package com.segersten.othello.service.akka.lobby;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.segersten.othello.model.Color;
import com.segersten.othello.service.akka.Auth;
import com.segersten.othello.service.akka.Player;


public class PlayerScores {

	private Map<Auth, List<Game>> ongoingGames = new HashMap<Auth, List<Game>>();
	private Map<BoardReference, List<Auth>> ongoingGames2 = new HashMap<BoardReference, List<Auth>>();
	private Map<Auth, PlayerScore> scores = new HashMap<Auth, PlayerScore>();
	private Map<String, Auth> nicknameMap = new HashMap<String, Auth>();

	public void gameFinished(BoardReference boardReference, Map<Auth, Integer> playerScores) {
		List<Auth> players = ongoingGames2.remove(boardReference);
		if (players==null) {
			System.out.println(String.format("Cannot give points to %s for %s", playerScores, boardReference));
			return;
		}
		for (Auth auth : players) {
			Integer score = playerScores.get(auth);
			if (score != null) {
				scores.get(auth).increase(score);
			}
			ongoingGames.get(auth).remove(new Game(boardReference, null));
		}
	}

	public PlayerScore getPoints(String nickname) {
		return getPoints(nicknameMap.get(nickname));
	}
	
	public PlayerScore getPoints(Auth auth) {
		return scores.get(auth);
	}

	public void addGame(BoardReference boardReference, Player player1, Player player2) {
	    ensurePlayerScore(player1);
	    ensurePlayerScore(player2);
		List<Game> ongoing1 = getOngoingAndLazyCreate(player1);
		List<Game> ongoing2 = getOngoingAndLazyCreate(player2);
		
		Map<Color, DomainPlayer> players = ImmutableMap.of(Color.BLACK, player1.domainPlayer(), Color.WHITE, player2.domainPlayer());
		Game game = new Game(boardReference, players);
		
		ongoing1.add(game);
		ongoing2.add(game);
        ongoingGames2.put(game.getBoardReference(), Lists.newArrayList(player1.getAuth(), player2.getAuth()));
	}

	private List<Game> getOngoingAndLazyCreate(Player player) {
		List<Game> list = ongoingGames.get(player.getAuth());
		if (list == null) {
			list = new ArrayList<Game>();
			ongoingGames.put(player.getAuth(), list);
		}
		return list;
	}

	public void ensurePlayerScore(Player player) {
		PlayerScore ps = scores.get(player.getAuth());
		if (ps == null) {
			ps = new PlayerScore(player);
			scores.put(player.getAuth(), ps);
			nicknameMap.put(player.getNickname(), player.getAuth());
		}
	}

	public List<Game> getOngoingGames(Auth auth) {
		List<Game> list = ongoingGames.get(auth);
        return (List<Game>) (list==null?Lists.newArrayList():list);
	}

    public void replace(Auth replacedSession, Auth newSession)
    {
        List<Game> games = ongoingGames.remove(replacedSession);
        if (games!=null) {
            ongoingGames.put(newSession, games);
            for(Game game : games) {
                List<Auth> games2 = ongoingGames2.get(game.getBoardReference());
                ArrayList<Auth> games3 = new ArrayList<Auth>();
                for(Auth auth : games2) {
                    if (auth.equals(replacedSession)) {
                        games3.add(newSession);
                    } else {
                        games3.add(auth);
                    }
                }
                ongoingGames2.put(game.getBoardReference(), games3);              
            }
        }
        PlayerScore ps = scores.remove(replacedSession);
        ps.setPlayer(new Player(ps.getPlayer().getNickname(), newSession));
        scores.put(newSession, ps);
        nicknameMap.put(ps.getPlayer().getNickname(), newSession);
    }

}
